<html>
<head><meta charset="utf-8"><title>Unstable trait impls · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html">Unstable trait impls</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="245438730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245438730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245438730">(Jul 09 2021 at 12:55)</a>:</h4>
<p>What would need to happen internally to permit unstable trait impls? If that is even desired.</p>



<a name="245439440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245439440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245439440">(Jul 09 2021 at 13:01)</a>:</h4>
<p>you'd have to make the trait selection logic aware of them at least</p>



<a name="245439599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245439599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245439599">(Jul 09 2021 at 13:03)</a>:</h4>
<p>theoretically, I believe we could even warn if an unstable impl is about to make some code ambiguous, by removing unstable impls during winnowing and emitting a warning there</p>



<a name="245439621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245439621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245439621">(Jul 09 2021 at 13:03)</a>:</h4>
<p>but I'm not sure if this would miss some edge case</p>



<a name="245455336"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245455336" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245455336">(Jul 09 2021 at 15:08)</a>:</h4>
<p>I think the bigger issue is that trait selection is (and has to be) "global", for soundness, but which unstable features are enabled is a "local" property</p>



<a name="245455460"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245455460" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245455460">(Jul 09 2021 at 15:09)</a>:</h4>
<p>so for every single possible trait query, you'd have to <em>not only</em> make an explicit <em>choice</em> of what's responsible for "the enabled unstable features set", but <em>also</em> somehow never cause such a query to happen again with a different choice</p>



<a name="245455623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245455623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245455623">(Jul 09 2021 at 15:10)</a>:</h4>
<p>the closest thing we can do is make an <code>impl</code> hidden from method selection, i.e. make method calls not resolve to a trait if the resulting <code>impl</code> is marked in a certain way. I believe this is how the <code>IntoIterator</code> for arrays issue was resolved</p>



<a name="245455822"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245455822" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245455822">(Jul 09 2021 at 15:12)</a>:</h4>
<p>that's pretty much only possible because the choice of where a method comes from is recorded. but how bounds got satisfied isn't, and is always recomputed (with caching). this is especially significant cross-crate</p>



<a name="245455901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245455901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245455901">(Jul 09 2021 at 15:13)</a>:</h4>
<p>you compile a function in a crate, and then codegen it by using it from another crate, the necessary trait impl selection gets done in the context of the latter</p>



<a name="245456008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456008">(Jul 09 2021 at 15:14)</a>:</h4>
<p>ah, yeah, so we could only fail compilation when trying to use an unstable impl, not warn and continue</p>



<a name="245456096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456096">(Jul 09 2021 at 15:15)</a>:</h4>
<p>hmm there's a thing that requires very little internal work, which is to inject certain unstable features into the <code>ParamEnv</code> of every generic definition which can observe them being enabled</p>



<a name="245456290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456290">(Jul 09 2021 at 15:16)</a>:</h4>
<p>i.e. pretend there's a <code>(): FooEnabled</code> bound in the <code>where</code> clauses, but don't require it of users of that generic</p>



<a name="245456350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456350">(Jul 09 2021 at 15:16)</a>:</h4>
<p>then the "unstable" impls can depend on <code>(): FooEnabled</code> (which can have a <code>#[rustc_on_unimplemented]</code> to explain itself etc.)</p>



<a name="245456440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456440">(Jul 09 2021 at 15:17)</a>:</h4>
<p>as long as the trait has no associated items, we can get away with never selecting it in codegen, and effectively treating it as an (erased) "axiom"</p>



<a name="245456538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245456538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245456538">(Jul 09 2021 at 15:18)</a>:</h4>
<p>and because it's like a weird sugar <em>on top of</em> an unmodified trait system, we get to keep all the soundness properties</p>



<a name="245457399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245457399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245457399">(Jul 09 2021 at 15:24)</a>:</h4>
<p><span class="user-mention silent" data-user-id="119009">eddyb</span> <a href="#narrow/stream/131828-t-compiler/topic/Unstable.20trait.20impls/near/245456440">said</a>:</p>
<blockquote>
<p>as long as the trait has no associated items, we can get away with never selecting it in codegen, and effectively treating it as an (erased) "axiom"</p>
</blockquote>
<p>heh just rememebred codegen might not even keep <code>ParamEnv</code>s today</p>



<a name="245460012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245460012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245460012">(Jul 09 2021 at 15:46)</a>:</h4>
<p>(it would be unsound to specialize on such feature marker traits unless we actually track <code>ParamEnv</code>s in codegen, but maybe we don't really want to enable specialization like that anyway, there might be more pitfalls)</p>



<a name="245464799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245464799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245464799">(Jul 09 2021 at 16:26)</a>:</h4>
<p>Would the same mechanism work for having visibility on trait impls?</p>



<a name="245464904"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245464904" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245464904">(Jul 09 2021 at 16:27)</a>:</h4>
<p>I would love to have actual private impls or <code>pub(crate)</code> impls, rather than the sealing pattern.</p>



<a name="245470419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245470419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245470419">(Jul 09 2021 at 17:10)</a>:</h4>
<p>tbh I would only use this hack sparingly. the fact that the sealing pattern exists <em>and works</em> makes me very dubious of considering a replacement for it</p>



<a name="245470552"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245470552" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245470552">(Jul 09 2021 at 17:11)</a>:</h4>
<p>also, the <code>FooEnabled</code> traits would be lang items. I don't know how would create similar traits in a stable way for users' own privacy boundaries</p>



<a name="245470708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245470708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245470708">(Jul 09 2021 at 17:13)</a>:</h4>
<p>oh also, the "paradoxical axiom" of having <code>(): FooEnabled</code> in the <code>ParamEnv</code> would only be triggered in unstable-feature-using code, which makes any issues with it far less grave IMO</p>



<a name="245499279"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245499279" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245499279">(Jul 09 2021 at 21:08)</a>:</h4>
<p>So not only would it be difficult (unsurprising given it hasn't been done), but it would likely have a notable performance impact?</p>



<a name="245499413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245499413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245499413">(Jul 09 2021 at 21:09)</a>:</h4>
<p>wrt private impls, that would also be nice but would presumably run into similar issues from what has been said. Having <code>#[sealed]</code> would still be nice</p>



<a name="245657463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245657463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245657463">(Jul 12 2021 at 08:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/131828-t-compiler/topic/Unstable.20trait.20impls/near/245499279">said</a>:</p>
<blockquote>
<p>So not only would it be difficult (unsurprising given it hasn't been done), but it would likely have a notable performance impact?</p>
</blockquote>
<p>why performance impact?</p>



<a name="245694874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245694874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245694874">(Jul 12 2021 at 14:38)</a>:</h4>
<p>It would add overhead to resolving every trait, no?</p>



<a name="245814759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245814759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245814759">(Jul 13 2021 at 12:13)</a>:</h4>
<p>hmm, the <code>ParamEnv</code>s would be different when type-checking anything in a crate that enables the feature. I guess I can see how uncached searches would take a small hit</p>



<a name="245814828"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/Unstable%20trait%20impls/near/245814828" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/Unstable.20trait.20impls.html#245814828">(Jul 13 2021 at 12:13)</a>:</h4>
<p>it shouldn't affect any stable code, or unstable code that doesn't use any of the unstable features that support this kind of "unstable trait <code>impl</code>" thing</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>